package dpe;

import static org.lwjgl.opengl.GL11.*;

import java.util.ArrayList;

import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;

public class Game {
	private boolean run = true;
	private ArrayList<World> worlds;
	private World currentWorld;
	private String title;
	private int width, height;
	private int syncFPS = 60;
	private String startWorld;
	private boolean fpsControl = false;
	private long lastFrame, lastFPS;
	private int frames, currentFPS;
	private boolean displayFPS = true;
	
	public Game() {
		worlds = new ArrayList<World>();
	}

	public void init() {
	}

	public void start() {
		Engine.log(0, "Starting game");
		try {
			Display.setDisplayMode(new DisplayMode(width, height));
			Display.setTitle(title);
			Display.create();
		} catch (LWJGLException e) {
			e.printStackTrace();
		}

		if (startWorld != null) {
			setWorld(startWorld);
		}
		
		lastFPS = Engine.getTime();
		
		new Thread(new Runnable() {
			public void run() {
				while (run) {
					int delta = getDelta();
					update(delta);

					render();
					Display.update();
					if (displayFPS) {
						Display.setTitle(Display.getTitle() + " | FPS: " + currentFPS);
					}
					Display.sync(syncFPS);

					if (Display.isCloseRequested()) {
						stop();
					}
				}
				Engine.log(0, "Game closed");
				Engine.exit(0);
			}
		}).run();
	}
	
	public void stop() {
		run = false;
	}

	public void addWorld(World world) {
		for (int i = 0; i < worlds.size(); i++) {
			if (worlds.get(i).getName().toLowerCase().equals(world.getName().toLowerCase())) {
				Engine.log(2, "Could not add world '" + world.getName() + "': Two worlds with the same name");
				Engine.exit(1);
			}
		}
		
		worlds.add(world);
		Engine.log(0, "Added world '" + world.getName() + "'");
	}

	public void setWorld(String name) {
		for (int i = 0; i < worlds.size(); i++) {
			if (worlds.get(i).getName().toLowerCase().equals(name.toLowerCase())) {
				Engine.log(0, "World set to '" + name + "'");
				return;
			}
		}
		Engine.log(1, "Could not find world '" + name + "'");
	}

	public void update(int delta) {
		if (currentWorld != null)
			currentWorld.update();
		
		if (Engine.getTime() - lastFPS > 1000) {
			currentFPS = frames;
			frames = 0;
			lastFPS += 1000;
		}
	}

	public void render() {
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		if (currentWorld != null)
			currentWorld.render();
	}
	
	public int getDelta() {
		return (int)(Engine.getTime() - lastFrame);
	}

	public void setWindowWidth(int w) {
		width = w;
		Engine.log(0, "Window width set to " + w);
	}

	public void setWindowHeight(int h) {
		height = h;
		Engine.log(0, "Window height set to " + h);
	}

	public void setWindowTitle(String t) {
		this.title = t;
		Engine.log(0, "Window title set to " + t);
	}

	public void setStartWorld(String t) {
		startWorld = t;
	}

	public boolean hasFPSControl() {
		return fpsControl;
	}
}
